//
//  KKQRCodeViewController.m
//  QRCodeDemo
//
//  Created by Mac mini on 16/1/19.
//  Copyright © 2016年 JuniorCodingPerson. All rights reserved.
//

#import "KKQRCodeViewController.h"
#import "KKAlertView.h"

typedef void(^KKQRCodeViewResultHandle)(NSString *restult);

@interface KKQRCodeView : UIView <AVCaptureMetadataOutputObjectsDelegate> {
    
    AVCaptureSession *_captureSession;
}

@property (nonatomic, copy) KKQRCodeViewResultHandle resultHandle;

@end

@implementation KKQRCodeView

- (instancetype)initWithDevice:(AVCaptureDevice *)device {
    
    //获取摄像设备
    if (device == nil) {
        //  设备不支持调用摄像头
        return nil;
    }
    
    CGFloat rootViewWidth = CGRectGetWidth([[UIScreen mainScreen] bounds]);
    CGFloat rootViewHeight = CGRectGetHeight([[UIScreen mainScreen] bounds]);
    
    self = [super initWithFrame: CGRectMake(0, 0, rootViewWidth, rootViewHeight)];
    if (self) {
        
        CGFloat pointX = (CGRectGetWidth(self.bounds) - 280)/2;
        CGFloat pointY = 180;
        CGFloat width = 280.0;
        CGFloat height = 280.0;
        
        if (device == nil) {
        }
        //创建输入流
        AVCaptureDeviceInput * input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
        //创建输出流
        AVCaptureMetadataOutput * output = [[AVCaptureMetadataOutput alloc]init];
        
        if (input == nil || output == nil) {
            return nil;
        }
        
        float pointXRatio = pointX / rootViewWidth;
        float pointYRatio = pointY / rootViewHeight;
        float widthRatio = width / rootViewWidth;
        float heightRatio = height / rootViewHeight;
        
        output.rectOfInterest = CGRectMake(pointYRatio, pointXRatio, heightRatio, widthRatio);
        
        //设置代理 在主线程里刷新
        [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
        
        //初始化链接对象
        _captureSession = [[AVCaptureSession alloc]init];
        //高质量采集率
        [_captureSession setSessionPreset:AVCaptureSessionPresetHigh];
        
        [_captureSession addInput:input];
        [_captureSession addOutput:output];
        //设置扫码支持的编码格式(如下设置条形码和二维码兼容)
        output.metadataObjectTypes=@[AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypeCode39Code];
        
        AVCaptureVideoPreviewLayer * layer = [AVCaptureVideoPreviewLayer layerWithSession: _captureSession];
        layer.videoGravity=AVLayerVideoGravityResizeAspectFill;
        layer.frame=self.layer.bounds;
        
        [self.layer insertSublayer:layer atIndex:0];
        
        [self initBackgroundViewWithRect: CGRectMake(pointX, pointY, width, height)];
        
    }
    return self;
}

- (void)startScanning {
    
    [_captureSession startRunning];
}

- (void)stopScanning {
    
    [_captureSession stopRunning];
}

- (void)initBackgroundViewWithRect:(CGRect)rect {
    
    UIColor *backgroundColor = [UIColor colorWithWhite:0.000 alpha:0.500];
    
    UIView *topView = [[UIView alloc] initWithFrame: CGRectMake(0, 0, CGRectGetWidth(self.bounds), CGRectGetMinY(rect))];
    topView.backgroundColor = backgroundColor;
    [self addSubview: topView];
    
    UIView *bottomView = [[UIView alloc] initWithFrame: CGRectMake(0, CGRectGetMaxY(rect), CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds) - CGRectGetMaxY(rect))];
    bottomView.backgroundColor = backgroundColor;
    [self addSubview: bottomView];
    
    UIView *leftView = [[UIView alloc] initWithFrame: CGRectMake(0, CGRectGetMinY(rect), CGRectGetMinX(rect), CGRectGetHeight(rect))];
    leftView.backgroundColor = backgroundColor;
    [self addSubview: leftView];
    
    UIView *rightView = [[UIView alloc] initWithFrame: CGRectMake(CGRectGetMaxX(rect), CGRectGetMinY(rect), CGRectGetWidth(self.bounds) - CGRectGetMaxX(rect), CGRectGetHeight(rect))];
    rightView.backgroundColor = backgroundColor;
    [self addSubview: rightView];
    
    NSString *imagePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"KKQRCodeViewController.bundle/KKQRcodeImages/"];
    
    UIImageView *imageView1 = [[UIImageView alloc] initWithFrame: CGRectMake(CGRectGetMinX(rect), CGRectGetMinY(rect), 16, 16)];
    imageView1.image = [UIImage imageWithContentsOfFile: [imagePath stringByAppendingPathComponent: @"ScanQR1@3x.png"]];
    [self addSubview: imageView1];
    
    UIImageView *imageView2 = [[UIImageView alloc] initWithFrame: CGRectMake(CGRectGetMaxX(rect) - 16, CGRectGetMinY(rect), 16, 16)];
    imageView2.image = [UIImage imageWithContentsOfFile: [imagePath stringByAppendingPathComponent: @"ScanQR2@3x.png"]];
    [self addSubview: imageView2];
    
    UIImageView *imageView3 = [[UIImageView alloc] initWithFrame: CGRectMake(CGRectGetMinX(rect), CGRectGetMaxY(rect) - 16, 16, 16)];
    imageView3.image = [UIImage imageWithContentsOfFile: [imagePath stringByAppendingPathComponent: @"ScanQR3@3x.png"]];
    [self addSubview: imageView3];
    
    UIImageView *imageView4 = [[UIImageView alloc] initWithFrame: CGRectMake(CGRectGetMaxX(rect) - 16, CGRectGetMaxY(rect) - 16, 16, 16)];
    imageView4.image = [UIImage imageWithContentsOfFile: [imagePath stringByAppendingPathComponent: @"ScanQR4@3x.png"]];
    [self addSubview: imageView4];
}

#pragma mark - AVCaptureMetadataOutputObjectsDelegate methods

-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
    if (metadataObjects.count>0) {
        //[session stopRunning];
        AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex : 0 ];
        //输出扫描字符串
        NSString *result = metadataObject.stringValue;
        
        if (_resultHandle && result) {
            _resultHandle(result);
            [self stopScanning];
        }
    }
}

@end


@interface KKQRCodeViewController ()  {
    
    UIToolbar *_kk_navigationBar;
    KKQRCodeView *_kk_codeView;
    
    NSString *_kk_resultValue;
}

@end

@implementation KKQRCodeViewController

- (void)loadView {
    [super loadView];

    UIView *rootView = self.view;
    rootView.backgroundColor = [UIColor blackColor];

    _kk_navigationBar = [[UIToolbar alloc] initWithFrame: CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), 64)];
    _kk_navigationBar.barStyle = UIBarStyleDefault;
    [rootView addSubview: _kk_navigationBar];
    {
        UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemCancel target: self action: @selector(actionOfCancel)];
        backButtonItem.tintColor = [UIColor blackColor];
        [_kk_navigationBar setItems: @[backButtonItem]];
    }
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
//    [self setBackEventBlock: nil];
    self.navigationItem.title = @"扫一扫";
    
    [self initWithCodeView];
    
    {
        CGFloat rootViewWidth = CGRectGetWidth([[UIScreen mainScreen] bounds]);
        CGFloat rootViewHeight = CGRectGetHeight([[UIScreen mainScreen] bounds]);
        
        UILabel *tipsLabel = [[UILabel alloc] initWithFrame: CGRectMake(10, rootViewHeight - 60, rootViewWidth - 20, 40)];
        tipsLabel.backgroundColor = [UIColor clearColor];
        tipsLabel.textAlignment = NSTextAlignmentCenter;
        tipsLabel.text = @"提示：扫描后的结果存在粘贴板中，直接在需要填写的地方粘贴使用即可";
        tipsLabel.font = [UIFont systemFontOfSize: 14];
        tipsLabel.textColor = [UIColor whiteColor];
        tipsLabel.numberOfLines = 0;
        [self.view addSubview: tipsLabel];
    }
    
    __weak typeof(self) weakSelf = self;
    _kk_codeView.resultHandle = ^(NSString *result){
        [[KKAlertView shareInterce] showWithTitle: @"扫描结果" andWithMessage: result andWithCancelTitle: @"重扫" andWithCancelHandle:^{
            [weakSelf codeViewDidStartScanning];
        } andWithSureTitle: @"确认" andWithSureHandle:^{
            
            _kk_resultValue = result;
            [weakSelf codeViewDidStopScanning];
        }];
    };
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear: animated];

    [self codeViewDidStartScanning];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear: animated];
    
    [_kk_codeView stopScanning];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Init methods

- (void)initWithCodeView {
    
    
    AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType: AVMediaTypeVideo];
    
    switch (authStatus) {
        case AVAuthorizationStatusNotDetermined:
        {
            __weak typeof(self) weakSelf = self;
            [AVCaptureDevice requestAccessForMediaType: AVMediaTypeVideo completionHandler:^(BOOL granted) {
                
                if (granted) {
                    [weakSelf initWithCodeView];
                }
                return;
            }];
        }
            break;
        case AVAuthorizationStatusRestricted:
        case AVAuthorizationStatusDenied:
        {
            [[KKAlertView shareInterce] showWithTitle: @"提示" andWithMessage: @"请在设备的\"设置-隐私-相机\"中允许访问相机权限" andWithCancelTitle: nil andWithCancelHandle: nil andWithSureTitle: @"关闭" andWithSureHandle: nil];
            return;
        }
            break;
        default:
            break;
    }
    
    //获取摄像设备
    AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo];
    _kk_codeView = [[KKQRCodeView alloc] initWithDevice: device];
    _kk_codeView.hidden = true;
    [self.view addSubview: _kk_codeView];
}

#pragma mark - Private methods

- (void)actionOfCancel {
    
    [self dismissViewControllerAnimated: true completion: nil];
}

- (void)codeViewDidStartScanning {
    
    _kk_codeView.hidden = false;
    _kk_codeView.alpha = CGFLOAT_MIN;
    
    [[UIApplication sharedApplication] beginIgnoringInteractionEvents];
    [UIView animateWithDuration: 0.25 animations:^{
        _kk_codeView.alpha = 1.0;
    } completion:^(BOOL finished) {
        [[UIApplication sharedApplication] endIgnoringInteractionEvents];
        [_kk_codeView startScanning];
    }];
}

- (void)codeViewDidStopScanning {
    
    [_kk_codeView stopScanning];
    if (self.resultBlock) {
        self.resultBlock(_kk_resultValue);
    }
    
    UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
    pasteboard.string = _kk_resultValue;
    
    [self.navigationController popViewControllerAnimated: true];
}

@end
